Naučite kako kreirati moćne API endpointe koristeći Next.js Route Handlers. Ovaj vodič pokriva sve, od osnovnog postavljanja do naprednih tehnika, s praktičnim primjerima i najboljim praksama.
Next.js Route Handlers: Sveobuhvatan Vodič za Kreiranje API Endpointa
Next.js je revolucionirao način на koji gradimo web aplikacije sa svojim moćnim značajkama kao što su renderiranje na strani poslužitelja, generiranje statičkih stranica, a sada i Route Handlers. Route Handlers pružaju fleksibilan i učinkovit način za kreiranje API endpointa izravno unutar vaše Next.js aplikacije. Ovaj vodič istražuje koncept Route Handlera, njihove prednosti i kako ih učinkovito koristiti za izgradnju robusnih API-ja.
Što su Next.js Route Handlers?
Route Handlers su funkcije definirane unutar app
direktorija Next.js projekta koje obrađuju dolazne HTTP zahtjeve. Za razliku od starijeg pages/api
pristupa (koji koristi API Routes), Route Handlers nude moderniji i fleksibilniji način definiranja API endpointa uz vaše React komponente. Oni su u suštini serverless funkcije koje se izvršavaju na rubu mreže (edge) ili u vašem odabranom poslužiteljskom okruženju.
Zamislite Route Handlers kao pozadinsku logiku vaše Next.js aplikacije, odgovornu za obradu zahtjeva, interakciju s bazama podataka i vraćanje odgovora.
Prednosti Korištenja Route Handlera
- Kolokacija: Route Handlers se nalaze izravno uz vaše React komponente unutar
app
direktorija, što promiče bolju organizaciju i održivost koda. - TypeScript podrška: Ugrađena TypeScript podrška osigurava sigurnost tipova i poboljšano iskustvo za programere.
- Integracija s Middlewareom: Jednostavna integracija s middlewareom za zadatke poput autentifikacije, autorizacije i validacije zahtjeva.
- Podrška za Streaming: Route Handlers mogu streamati podatke, omogućujući vam slanje odgovora inkrementalno, što je korisno za velike skupove podataka ili dugotrajne procese.
- Edge Funkcije: Implementirajte Route Handlers kao Edge funkcije za odgovore niske latencije bliže vašim korisnicima, koristeći globalne CDN-ove.
- Pojednostavljen dizajn API-ja: Route Handlers pružaju čist i intuitivan API za obradu zahtjeva i odgovora.
- Integracija sa Server Actions: Čvrsta integracija sa Server Actions omogućuje besprijekornu komunikaciju između vaših klijentskih komponenti i poslužiteljske logike.
Postavljanje Vašeg Next.js Projekta
Prije nego što zaronite u Route Handlers, provjerite imate li postavljen Next.js projekt s app
direktorijem. Ako započinjete novi projekt, koristite sljedeću naredbu:
npx create-next-app@latest my-nextjs-app
Odaberite app
direktorij tijekom procesa postavljanja kako biste omogućili novi sustav rutiranja.
Kreiranje Vašeg Prvog Route Handlera
Kreirajmo jednostavan API endpoint koji vraća JSON odgovor. Stvorite novi direktorij unutar app
direktorija, na primjer, /app/api/hello
. Unutar tog direktorija, stvorite datoteku pod nazivom route.ts
(ili route.js
ako ne koristite TypeScript).
Evo koda za vaš prvi Route Handler:
// app/api/hello/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
return NextResponse.json({ message: 'Pozdrav od Next.js Route Handlera!' });
}
Objašnjenje:
import { NextResponse } from 'next/server';
: UvoziNextResponse
objekt, koji se koristi za konstruiranje API odgovora.export async function GET(request: Request) { ... }
: Definira asinkronu funkciju koja obrađuje GET zahtjeve na/api/hello
endpoint. Parametarrequest
pruža pristup dolaznom objektu zahtjeva.return NextResponse.json({ message: 'Pozdrav od Next.js Route Handlera!' });
: Kreira JSON odgovor s porukom i vraća ga pomoćuNextResponse.json()
.
Sada možete pristupiti ovom endpointu navigacijom na /api/hello
u vašem pregledniku ili korištenjem alata kao što su curl
ili Postman
.
Obrada Različitih HTTP Metoda
Route Handlers podržavaju različite HTTP metode kao što su GET, POST, PUT, DELETE, PATCH i OPTIONS. Možete definirati zasebne funkcije za svaku metodu unutar iste route.ts
datoteke.
// app/api/users/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// Logika za dohvaćanje svih korisnika iz baze podataka
const users = [{ id: 1, name: 'Ivan Ivić' }, { id: 2, name: 'Ana Anić' }]; // Primjer podataka
return NextResponse.json(users);
}
export async function POST(request: Request) {
const data = await request.json(); // Parsirajte tijelo zahtjeva kao JSON
// Logika za kreiranje novog korisnika u bazi podataka koristeći 'data'
const newUser = { id: 3, name: data.name, email: data.email }; // Primjer
return NextResponse.json(newUser, { status: 201 }); // Vratite novog korisnika sa statusnim kodom 201 Created
}
Objašnjenje:
GET
funkcija dohvaća listu korisnika (ovdje simulirano) i vraća je kao JSON odgovor.POST
funkcija parsira tijelo zahtjeva kao JSON, kreira novog korisnika (simulirano) i vraća novog korisnika sa statusnim kodom 201 Created.
Pristupanje Podacima iz Zahtjeva
Objekt request
pruža pristup različitim informacijama o dolaznom zahtjevu, uključujući zaglavlja, parametre upita i tijelo zahtjeva.
Zaglavlja (Headers)
Možete pristupiti zaglavljima zahtjeva koristeći svojstvo request.headers
:
export async function GET(request: Request) {
const userAgent = request.headers.get('user-agent');
console.log('User Agent:', userAgent);
return NextResponse.json({ userAgent });
}
Parametri Upita (Query Parameters)
Za pristup parametrima upita, možete koristiti URL
konstruktor:
export async function GET(request: Request) {
const url = new URL(request.url);
const searchParams = new URLSearchParams(url.search);
const id = searchParams.get('id');
console.log('ID:', id);
return NextResponse.json({ id });
}
Tijelo Zahtjeva (Request Body)
Za POST, PUT i PATCH zahtjeve, možete pristupiti tijelu zahtjeva koristeći metode request.json()
ili request.text()
, ovisno o tipu sadržaja.
export async function POST(request: Request) {
const data = await request.json();
console.log('Podaci:', data);
return NextResponse.json({ primljeniPodaci: data });
}
Vraćanje Odgovora
Objekt NextResponse
se koristi za konstruiranje API odgovora. Pruža nekoliko metoda za postavljanje zaglavlja, statusnih kodova i tijela odgovora.
JSON Odgovori
Koristite metodu NextResponse.json()
za vraćanje JSON odgovora:
return NextResponse.json({ message: 'Uspjeh!', data: { name: 'Ivan Ivić' } }, { status: 200 });
Tekstualni Odgovori
Koristite konstruktor new Response()
za vraćanje običnih tekstualnih odgovora:
return new Response('Pozdrav, svijete!', { status: 200, headers: { 'Content-Type': 'text/plain' } });
Preusmjeravanja (Redirects)
Koristite NextResponse.redirect()
za preusmjeravanje korisnika na drugu URL adresu:
import { redirect } from 'next/navigation';
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
return NextResponse.redirect(new URL('/nova-lokacija', request.url));
}
Postavljanje Zaglavlja (Headers)
Možete postaviti prilagođena zaglavlja koristeći opciju headers
u NextResponse.json()
ili new Response()
:
return NextResponse.json({ message: 'Uspjeh!' }, { status: 200, headers: { 'Cache-Control': 'no-cache' } });
Integracija s Middlewareom
Middleware vam omogućuje izvršavanje koda prije nego što vaš Route Handler obradi zahtjev. To je korisno za autentifikaciju, autorizaciju, logiranje i druge poprečne zadatke (cross-cutting concerns).
Da biste kreirali middleware, stvorite datoteku pod nazivom middleware.ts
(ili middleware.js
) u app
direktoriju ili bilo kojem poddirektoriju. Middleware će se primijeniti na sve rute unutar tog direktorija i njegovih poddirektorija.
// app/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth-token');
if (!token) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/protected/:path*'], // Primijeni ovaj middleware na putanje koje počinju s /protected/
};
Objašnjenje:
- Funkcija
middleware
provjerava postoji li token za autentifikaciju u kolačićima zahtjeva. - Ako token nedostaje, preusmjerava korisnika na stranicu za prijavu.
- Inače, dopušta da se zahtjev nastavi prema Route Handleru.
- Objekt
config
specificira da se ovaj middleware treba primijeniti samo na rute koje počinju s/protected/
.
Obrada Grešaka
Pravilna obrada grešaka ključna je za izgradnju robusnih API-ja. Možete koristiti try...catch
blokove za obradu iznimaka i vraćanje odgovarajućih odgovora o greškama.
export async function GET(request: Request) {
try {
// Simuliraj grešku
throw new Error('Nešto je pošlo po zlu!');
} catch (error: any) {
console.error('Greška:', error);
return NextResponse.json({ error: error.message }, { status: 500 });
}
}
Objašnjenje:
try...catch
blok hvata sve iznimke koje se dogode unutar Route Handlera.- U
catch
bloku, greška se bilježi, a odgovor o grešci vraća se sa statusnim kodom 500 Internal Server Error.
Streaming Odgovori
Route Handlers podržavaju streaming odgovore, što vam omogućuje inkrementalno slanje podataka klijentu. To je posebno korisno za velike skupove podataka ili dugotrajne procese.
import { Readable } from 'stream';
import { NextResponse } from 'next/server';
async function* generateData() {
for (let i = 0; i < 10; i++) {
await new Promise(resolve => setTimeout(resolve, 500)); // Simuliraj kašnjenje
yield `Podatkovni dio ${i}\n`;
}
}
export async function GET(request: Request) {
const readableStream = Readable.from(generateData());
return new Response(readableStream, {
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
});
}
Objašnjenje:
- Funkcija
generateData
je asinkroni generator koji isporučuje dijelove podataka s kašnjenjem. - Metoda
Readable.from()
stvara čitljivi stream iz generatora. - Objekt
Response
se stvara s čitljivim streamom kao tijelom, a zaglavljeContent-Type
postavljeno je natext/plain
.
Autentifikacija i Autorizacija
Osiguravanje vaših API endpointa je ključno. Možete implementirati autentifikaciju i autorizaciju koristeći middleware ili izravno unutar vaših Route Handlera.
Autentifikacija
Autentifikacija provjerava identitet korisnika koji šalje zahtjev. Uobičajene metode autentifikacije uključuju:
- JWT (JSON Web Tokens): Generirajte token nakon uspješne prijave i provjerite ga pri svakom sljedećem zahtjevu.
- Autentifikacija temeljena na sesiji: Koristite kolačiće za pohranu identifikatora sesije i provjeravajte ih pri svakom zahtjevu.
- OAuth: Delegirajte autentifikaciju trećoj strani poput Googlea ili Facebooka.
Evo primjera JWT autentifikacije pomoću middlewarea:
// app/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import jwt from 'jsonwebtoken';
const secret = process.env.JWT_SECRET || 'vasa-tajna-sifra'; // Zamijenite s jakom, nasumično generiranom tajnom
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth-token')?.value;
if (!token) {
return NextResponse.json({ message: 'Potrebna je autentifikacija' }, { status: 401 });
}
try {
jwt.verify(token, secret);
return NextResponse.next();
} catch (error) {
return NextResponse.json({ message: 'Nevažeći token' }, { status: 401 });
}
}
export const config = {
matcher: ['/api/protected/:path*'],
};
Autorizacija
Autorizacija određuje kojim resursima korisnik smije pristupiti. To se obično temelji na ulogama ili dopuštenjima.
Možete implementirati autorizaciju unutar vaših Route Handlera provjerom korisničkih uloga ili dopuštenja i vraćanjem greške ako nemaju pristup.
// app/api/admin/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// Pretpostavimo da imate funkciju za dohvaćanje uloge korisnika iz tokena ili sesije
const userRole = await getUserRole(request);
if (userRole !== 'admin') {
return NextResponse.json({ message: 'Neovlašteno' }, { status: 403 });
}
// Logika za dohvaćanje administratorskih podataka
const adminData = { message: 'Administratorski podaci' };
return NextResponse.json(adminData);
}
async function getUserRole(request: Request): Promise {
// Zamijenite s vašom stvarnom logikom za izdvajanje uloge korisnika iz zahtjeva
// To može uključivati provjeru JWT tokena ili sesije
return 'admin'; // Primjer: fiksno postavljena uloga za demonstraciju
}
Implementacija (Deploying) Route Handlera
Route Handlers se implementiraju kao serverless funkcije na vašem odabranom hosting provideru. Next.js podržava različite platforme za implementaciju, uključujući Vercel, Netlify, AWS i druge.
Za Vercel, implementacija je jednostavna kao povezivanje vašeg Git repozitorija s Vercelom i guranje vašeg koda. Vercel automatski detektira vaš Next.js projekt i implementira vaše Route Handlers kao serverless funkcije.
Napredne Tehnike
Edge Funkcije
Route Handlers se mogu implementirati kao Edge funkcije, koje se izvršavaju na rubu CDN mreže, bliže vašim korisnicima. To može značajno smanjiti latenciju i poboljšati performanse.
Da biste implementirali Route Handler kao Edge funkciju, dodajte edge
runtime u vašu route.ts
datoteku:
export const runtime = 'edge';
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
return NextResponse.json({ message: 'Pozdrav s Edge-a!' });
}
Server Actions
Server Actions vam omogućuju izvršavanje koda na strani poslužitelja izravno iz vaših React komponenti. Route Handlers i Server Actions rade besprijekorno zajedno, omogućujući vam da s lakoćom gradite složene aplikacije.
Evo primjera korištenja Server Action za pozivanje Route Handlera:
// app/components/MyComponent.tsx
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
async function handleSubmit(data: FormData) {
'use server';
const name = data.get('name');
const email = data.get('email');
const response = await fetch('/api/users', {
method: 'POST',
body: JSON.stringify({ name, email }),
});
if (response.ok) {
router.refresh(); // Osvježite stranicu kako bi se promjene prikazale
}
}
export default function MyComponent() {
const router = useRouter();
return (
);
}
Predmemoriranje (Caching)
Predmemoriranje može značajno poboljšati performanse vaših API endpointa. Možete koristiti Cache-Control
zaglavlje za kontrolu načina na koji preglednici i CDN-ovi predmemoriraju vaše odgovore.
return NextResponse.json({ message: 'Uspjeh!' }, { status: 200, headers: { 'Cache-Control': 'public, max-age=3600' } });
Ovaj primjer postavlja Cache-Control
zaglavlje na public, max-age=3600
, što govori preglednicima i CDN-ovima da predmemoriraju odgovor na jedan sat.
Najbolje Prakse
- Koristite TypeScript: Iskoristite sigurnost tipova TypeScripta za poboljšanje kvalitete koda i sprječavanje grešaka.
- Validirajte Zahtjeve: Validirajte dolazne zahtjeve kako biste osigurali integritet podataka i spriječili zlonamjerni unos.
- Elegantno Rješavajte Greške: Implementirajte pravilnu obradu grešaka kako biste klijentima pružili informativne poruke o greškama.
- Osigurajte Svoje Endpointe: Implementirajte autentifikaciju i autorizaciju za zaštitu svojih API endpointa.
- Koristite Middleware: Koristite middleware za poprečne zadatke poput autentifikacije, logiranja i validacije zahtjeva.
- Predmemorirajte Odgovore: Koristite predmemoriranje za poboljšanje performansi vaših API endpointa.
- Nadzirite Svoje API-je: Nadzirite svoje API-je kako biste brzo identificirali i riješili probleme.
- Dokumentirajte Svoje API-je: Dokumentirajte svoje API-je kako bi ih drugi programeri mogli lako koristiti. Razmislite o korištenju alata kao što su Swagger/OpenAPI za dokumentaciju API-ja.
Primjeri iz Stvarnog Svijeta
Evo nekoliko primjera iz stvarnog svijeta kako se Route Handlers mogu koristiti:
- API za e-trgovinu: Kreirajte API endpointe za upravljanje proizvodima, narudžbama i korisnicima.
- API za društvene mreže: Kreirajte API endpointe za objavljivanje tvitova, praćenje korisnika i dohvaćanje vremenskih crta.
- API za sustav za upravljanje sadržajem (CMS): Kreirajte API endpointe za upravljanje sadržajem, korisnicima i postavkama.
- API za analitiku podataka: Kreirajte API endpointe za prikupljanje i analizu podataka. Na primjer, Route Handler bi mogao primati podatke od piksela za praćenje na različitim web stranicama i agregirati informacije za izvještavanje.
Primjer međunarodne e-trgovine: Route Handler koji se koristi za dohvaćanje cijena proizvoda na temelju zemlje korisnika. Endpoint bi mogao koristiti geolokaciju zahtjeva (dobivenu iz IP adrese) kako bi odredio lokaciju korisnika i vratio cijene u odgovarajućoj valuti. To doprinosi lokaliziranom iskustvu kupovine.
Primjer globalne autentifikacije: Route Handler koji implementira višefaktorsku autentifikaciju (MFA) za korisnike diljem svijeta. To bi moglo uključivati slanje SMS kodova ili korištenje aplikacija za autentifikaciju, uz poštivanje propisa o privatnosti i telekomunikacijskih infrastruktura različitih regija.
Isporuka višejezičnog sadržaja: Route Handler koji isporučuje sadržaj na preferiranom jeziku korisnika. To se može odrediti iz Accept-Language
zaglavlja u zahtjevu. Ovaj primjer naglašava potrebu za pravilnim UTF-8 kodiranjem i podrškom za jezike koji se pišu s desna na lijevo gdje je to prikladno.
Zaključak
Next.js Route Handlers pružaju moćan и fleksibilan način za kreiranje API endpointa izravno unutar vaše Next.js aplikacije. Korištenjem Route Handlera, možete s lakoćom graditi robusne API-je, kolocirati vašu pozadinsku logiku s vašim React komponentama i iskoristiti značajke poput middlewarea, streaminga i Edge funkcija.
Ovaj sveobuhvatni vodič pokrio je sve, od osnovnog postavljanja do naprednih tehnika. Slijedeći najbolje prakse navedene u ovom vodiču, možete izgraditi visokokvalitetne API-je koji su sigurni, performantni i održivi.